// -------------------------------------------------
// BlinKit - BlinKit Library
// -------------------------------------------------
//   File Name: qjs_option_element.cpp
// Description: Bindings for HTMLOptionElement
//      Author: Ziming Li
//     Created: 2022-04-29
// -------------------------------------------------
// Copyright (C) 2022 MingYang Software Technology.
// -------------------------------------------------

#include "./qjs_bindings.h"

#include "blinkit/blink/renderer/bindings/core/qjs/qjs.h"
#include "blinkit/blink/renderer/bindings/core/qjs/qjs_c_function_list_entries.h"
#include "blinkit/blink/renderer/bindings/core/script_controller.h"
#include "blinkit/blink/renderer/core/HTMLNames.h"
#include "blinkit/blink/renderer/core/html/HTMLOptionElement.h"

/**
 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptionElement
 */

using namespace blink::HTMLNames;

namespace BlinKit {
namespace qjs {

static JSValue GetDisabled(JSContext *ctx, JSValueConst thisVal)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);
    return JS_NewBool(ctx, option->fastHasAttribute(HTMLNames::disabledAttr));
}

static JSValue GetLabel(JSContext *ctx, JSValueConst thisVal)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);
    return WrapString(ctx, option->label());
}

static JSValue GetSelected(JSContext *ctx, JSValueConst thisVal)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);
    return JS_NewBool(ctx, option->selectedForBinding());
}

static JSValue GetValue(JSContext *ctx, JSValueConst thisVal)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);
    return WrapString(ctx, option->value());
}

static JSValue SetDisabled(JSContext *ctx, JSValueConst thisVal, JSValueConst disabled)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);

    option->setBooleanAttribute(HTMLNames::disabledAttr, JS_ToBool(ctx, disabled));
    return JS_NewBool(ctx, option->fastHasAttribute(HTMLNames::disabledAttr));
}

static JSValue SetLabel(JSContext *ctx, JSValueConst thisVal, JSValueConst label)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);

    option->setLabel(ToAtomicString(ctx, label));
    return WrapString(ctx, option->label());
}

static JSValue SetSelected(JSContext *ctx, JSValueConst thisVal, JSValueConst selected)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);

    option->setSelectedForBinding(JS_ToBool(ctx, selected));
    return JS_NewBool(ctx, option->selectedForBinding());
}

static JSValue SetValue(JSContext *ctx, JSValueConst thisVal, JSValueConst value)
{
    HTMLOptionElement *option = ScriptWrappable::Cast<HTMLOptionElement>(thisVal);

    option->setValue(ToAtomicString(ctx, value));
    return WrapString(ctx, option->value());
}

JSValue CreateOptionElementPrototype(JSContext *ctx, JSValue elementPrototype)
{
    static const JSCFunctionListEntry Funcs[] = {
        CGetSetEntry(Strings::Disabled, GetDisabled, SetDisabled),
        CGetSetEntry("label", GetLabel, SetLabel),
        CGetSetEntry("selected", GetSelected, SetSelected),
        CGetSetEntry(Strings::Value, GetValue, SetValue)
    };

    JSValue ret = JS_NewObjectProto(ctx, elementPrototype);
    JS_SetPropertyFunctionList(ctx, ret, Funcs, std::size(Funcs));
    return ret;
}

} // namespace qjs
} // namespace BlinKit
